// backend/src/config/auth.js
import jwt from 'jsonwebtoken';
import redisClient from './redisClient.js';
import fs from 'fs';
import yaml from 'js-yaml';
import ResponseHandler from "../utils/responseHandler.js";

const config = yaml.load(fs.readFileSync('./src/application.yaml', 'utf8'));

const authConfig = config.auth;

/**
 * @description 生成 JWT 令牌
 * @param {Object} user - 用户信息
 * @returns {Promise<string>} 返回生成的 JWT 令牌
 * @throws {ResponseHandler} 如果生成 token 失败
 */
const generateToken = async (user) => {
    const key = `token:${user.user_id}`; // 生成唯一的 Redis 键
    const loginTime = Date.now();
    const calculatedExpireTime = loginTime + (authConfig.time * 1000) - 3000;


    try {
        // 从 Redis 中查找 token 和过期时间
        const existingToken = await redisClient.get(key);
        let tokenData = existingToken ? JSON.parse(existingToken) : null;

        // 如果存在 token 并且未过期，直接返回
        if (tokenData?.token && tokenData.expireTime > loginTime) {
            return tokenData.token;
        }

        // 删除过期的 token
        if (tokenData?.token) {
            await redisClient.del(key);
        }

        // 生成新的 JWT 令牌
        const newToken = jwt.sign({
            id: user.id,
            // role_id: user.role_id
        }, authConfig.secretKey, {expiresIn: authConfig.time});1

        // 存储新 token 和过期时间到 Redis
        const tokenDataToStore = {
            user: user,
            token: newToken,
            expireTime: calculatedExpireTime
        };
        await redisClient.set(key, JSON.stringify(tokenDataToStore), {
            EX: authConfig.time // 设置过期时间为秒
        });

        return newToken;
    } catch (error) {
        throw new ResponseHandler.responseResult(error, '没有生成token');
    }
};

/**
 * @description JWT 验证中间件
 * @param {Object} req - 请求对象
 * @param {Object} res - 响应对象
 * @param {Function} next - 下一个中间件
 */
const authenticateToken = (req, res, next) => {
    const token = req.headers['authorization']?.split(' ')[1];

    if (!token) return ResponseHandler.responseResult(res);

    jwt.verify(token, authConfig.secretKey, (err, user) => {
        if (err) return ResponseHandler.responseResult(res, "token权限过期");
        req.user = user; // 存储解码的用户信息
        next();
    });
};


export {generateToken, authenticateToken};
